// 一、为什么不加管道会 “发一个字符、打一个字符”？
// 之前纯共享内存的同步逻辑是 “检测内存非空就读取”：
// Client 写字符时是逐个写入（比如写 “Hello”，先写 'H'、再写 'e'、再写 'l'…）；
// Server 一直在轮询共享内存，只要检测到内存非空（哪怕只有一个字符），
// 就会立刻读取并打印，导致 “写一个、读一个、打一个”。
// 核心问题是：没有 “整段写完” 的信号，Server 不知道什么时候 Client 已经把完整字符串写完了，
// 只能靠 “有数据就读”，自然无法实现整段打印。
// 二、管道的核心作用：传递 “整段写完” 的通知信号
// 管道加入后，相当于在 “写数据” 和 “读数据” 之间加了一个 “发令枪”：
// Client 流程：先把一整段字符串完整写入共享内存（比如写完 “Hello Server”）→ 向管道写 1 字节
// （相当于扣动 “发令枪”，通知 Server“我写完一段了，快来读”）；
// Server 流程：一直阻塞在管道的 read 操作上（等待 “发令枪”）→ 收到管道信号后，
// 才从共享内存读取 整段字符串 并打印→ 打印完清空内存，再回到管道等待下一次通知。
// #include "Shm.hpp"
// #include "Fifo.hpp" // 包含管道类
// #include <cstring>

// int main() {
//     Shm shm(pathname, projid, CREATER);
//     shm.Attr();
//     char *mem = (char *)shm.VirtualAddr();

//     // 管道初始化（读端，Server 用）
//     NameFifo fifo(PATH, FILENAME);
//     FileOper reader(PATH, FILENAME);
//     reader.OpenForRead();

//     printf("Server: 等待接收整段字符串（收到空字符串退出）...\n");
//     while (true) {
//         // 阻塞等待管道通知（替代字符级轮询，直到 Client 写完一段）
//         if (!reader.Wait()) break;

//         // 收到通知后，读取整段字符串并打印
//         if (strlen(mem) > 0) {
//             printf("Server 收到整段字符串：%s\n", mem);
//             // 清空内存，准备接收下一段
//             memset(mem, 0, shm.Size());
//         }
//     }

//     reader.Close();
//     printf("Server 退出\n");
//     return 0;
// }
#include "Shm.hpp"
#include "Fifo.hpp"

int main()
{
    Shm shm(pathname, projid, CREATER);
    // sleep(5);
    shm.Attr();


    NameFifo fifo(PATH, FILENAME);

    // 文件操作了
    FileOper readerfile(PATH, FILENAME);
    readerfile.OpenForRead();

    char *mem = (char *)shm.VirtualAddr();
    // 我们读写共享内存，有没有使用系统调用？？也没有！！
    while (true)
    {
        if (readerfile.Wait())
        {
            printf("%s\n", mem);
        }
        else
            break;
    }

    readerfile.Close();
    std::cout << "server end normal!" << std::endl; // server段的析构函数没有被成功调用！
    return 0;
}